<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VSCode风格文件资源管理器</title>
    <style>
        /* 全局样式重置 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
            display: flex;
            flex-direction: column;
            height: 100vh;
            overflow: hidden;
            background-color: #1e1e1e;
            color: #d4d4d4;
        }

        /* 顶部状态栏 */
        .status-bar {
            height: 24px;
            background-color: #007acc;
            color: white;
            display: flex;
            align-items: center;
            padding: 0 10px;
            font-size: 12px;
            line-height: 24px;
        }

        /* 主容器 */
        .main-container {
            display: flex;
            flex: 1;
            overflow: hidden;
        }

        /* 左侧目录树 */
        .sidebar {
            width: 300px;
            background-color: #252526;
            border-right: 1px solid #3e3e42;
            display: flex;
            flex-direction: column;
        }

        .sidebar-header {
            padding: 10px;
            background-color: #1e1e1e;
            border-bottom: 1px solid #3e3e42;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .sidebar-actions {
            display: flex;
            align-items: baseline;
            gap: 12px;
        }

        .connection-indicator {
            font-size: 20px;
            color: #f44336; /* 未连接状态：红色 */
            cursor: help;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            line-height: 1;
            padding: 4px;
            border-radius: 3px;
        }

        .connection-indicator:hover {
            background-color: #3e3e42;
        }

        .connection-indicator.connecting {
            color: #ff9800; /* 连接中：橙色 */
        }

        .connection-indicator.connected {
            color: #4caf50; /* 已连接：绿色 */
        }

        .sidebar-header h3 {
            font-size: 14px;
            font-weight: 500;
            color: #cccccc;
        }

        .refresh-btn {
            background: none;
            border: none;
            color: #cccccc;
            cursor: pointer;
            padding: 4px;
            border-radius: 3px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
            line-height: 1;
        }

        .refresh-btn:hover {
            background-color: #3e3e42;
        }

        .collapse-btn {
            background: none;
            border: none;
            color: #cccccc;
            cursor: pointer;
            padding: 4px;
            border-radius: 3px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
            line-height: 1;
        }

        .collapse-btn:hover {
            background-color: #3e3e42;
        }
        .file-tree {
            flex: 1;
            overflow-y: auto;
            padding: 5px 0;
        }

        .tree-node {
            padding: 4px 10px;
            cursor: pointer;
            display: flex;
            align-items: center;
            font-size: 13px;
        }

        .tree-node:hover {
            background-color: #2a2d2e;
        }

        .tree-node.selected {
            background-color: #0e639c;
            color: white;
        }

        .tree-node.folder {
            font-weight: 500;
        }

        .expand-icon {
            width: 16px;
            height: 16px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            margin-right: 2px;
            transition: transform 0.15s ease;
            transform-origin: center;
            cursor: pointer;
        }

        .expand-icon::before {
            content: '';
            width: 0;
            height: 0;
            border-top: 3px solid transparent;
            border-bottom: 3px solid transparent;
            border-left: 5px solid #666;
        }

        .expand-icon.expanded {
            transform: rotate(90deg);
        }

        .tree-indent {
            display: inline-block;
            width: 16px;
        }

        .children-container {
            margin-left: 16px; /* 固定缩进量，参考VSCode */
        }

        .icon {
            width: 16px;
            height: 16px;
            margin-right: 5px;
            display: inline-block;
            text-align: center;
            font-size: 16px;
        }

        .folder-icon {
            content: "📁";
        }

        .file-icon {
            content: "📄";
        }
        
        .file-size {
            margin-left: auto;
            font-size: 12px;
            color: #666666;
            float: right;
            padding-right: 10px;
        }
        
        .tree-node {
            display: flex;
            align-items: center;
            padding: 3px 0;
            cursor: pointer;
            border-radius: 3px;
            height: 20px;
        }
        
        .icon {
            width: 16px;
            height: 16px;
            margin-right: 5px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
        }
        
        .tree-node:hover {
            background-color: #2a2d2e;
        }
        
        .tree-node.selected {
            background-color: #0e639c;
            color: white;
        }
        
        .tree-node.selected .file-size {
            color: #cccccc;
        }

        /* 右侧编辑窗口 */
        .editor-container {
            flex: 1;
            display: flex;
            flex-direction: column;
            background-color: #1e1e1e;
        }

        /* 标签栏样式 */
        .tabs-container {
            display: flex;
            align-items: center;
            background-color: #2d2d30;
            border-bottom: 1px solid #3e3e42;
            padding: 0 5px;
            min-height: 28px;
        }

        .tabs {
            display: flex;
            align-items: center;
            gap: 2px;
            overflow-x: auto;
            flex: 1;
        }

        .tabs::-webkit-scrollbar {
            height: 4px;
        }

        .tab {
            display: flex;
            align-items: center;
            padding: 4px 10px;
            background-color: #1e1e1e;
            border: 1px solid #3e3e42;
            border-bottom: none;
            border-radius: 3px 3px 0 0;
            font-size: 13px;
            color: #cccccc;
            cursor: pointer;
            white-space: nowrap;
            position: relative;
            height: 24px;
        }

        .tab:hover {
            background-color: #2a2d2e;
        }

        .tab.active {
            background-color: #2d2d30;
            color: #ffffff;
            border-color: #007acc;
            border-bottom: 1px solid #2d2d30;
            font-weight: 600;
            box-shadow: 0 1px 0 0 #007acc;
        }

        .tab-modified-indicator {
            width: 8px;
            height: 8px;
            background-color: white;
            border-radius: 50%;
            margin-left: 4px;
            margin-right: 4px;
            display: none;
        }
        
        .tab-close {
            margin-left: 1px;
            width: 16px;
            height: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            color: #cccccc;
            cursor: pointer;
            border-radius: 2px;
        }

        .tab-close:hover {
            background-color: #f44336;
            color: white;
        }

        .tabs-actions {
            display: flex;
            align-items: center;
            padding-left: 5px;
        }

        .tab-action-btn {
            width: 24px;
            height: 24px;
            background-color: transparent;
            border: none;
            color: #cccccc;
            cursor: pointer;
            border-radius: 2px;
            font-size: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .tab-action-btn:hover {
            background-color: #2a2d2e;
        }
        
        /* 保存状态提示 */
        .save-status {
            position: fixed;
            top: 20px;
            right: 20px;
            background-color: #4caf50;
            color: white;
            padding: 10px 20px;
            border-radius: 4px;
            font-size: 14px;
            z-index: 1000;
            opacity: 0.9;
            animation: fadeIn 0.3s ease-in-out;
        }
        
        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(-10px);
            }
            to {
                opacity: 0.9;
                transform: translateY(0);
            }
        }

        .editor-header {
            padding: 8px 15px;
            background-color: #2d2d30;
            border-bottom: 1px solid #3e3e42;
            display: flex;
            align-items: center;
            font-size: 13px;
        }

        .editor-title {
            color: #cccccc;
            font-weight: 500;
        }

        .editor-content {
            flex: 1;
            overflow: hidden;
            display: flex;
            flex-direction: column;
        }

        .editor-empty {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666666;
            font-size: 16px;
        }

        .code-editor {
            flex: 1;
            background-color: #1e1e1e;
            color: #d4d4d4;
            border: none;
            outline: none;
            padding: 15px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.5;
            resize: none;
        }

        /* 状态栏 */
        .editor-footer {
            height: 24px;
            background-color: #1e1e1e;
            border-top: 1px solid #3e3e42;
            display: flex;
            align-items: center;
            padding: 0 15px;
            font-size: 12px;
            color: #cccccc;
        }

        /* 右键菜单 */
        .context-menu {
            position: fixed;
            background-color: #2d2d30;
            border: 1px solid #3e3e42;
            border-radius: 3px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
            display: none;
            z-index: 1000;
        }

        .context-menu-item {
            padding: 8px 15px;
            cursor: pointer;
            font-size: 13px;
            color: #cccccc;
        }

        .context-menu-item:hover {
            background-color: #0e639c;
            color: white;
        }
        
        .context-menu-divider {
            height: 1px;
            background-color: #3e3e42;
            margin: 2px 0;
        }

        /* 滚动条样式 */
        ::-webkit-scrollbar {
            width: 10px;
            height: 10px;
        }

        ::-webkit-scrollbar-track {
            background: #1e1e1e;
        }

        ::-webkit-scrollbar-thumb {
            background: #424242;
            border-radius: 5px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: #4e4e4e;
        }
    /* Shell调试区样式 */
        .shell-container {
            height: 300px;
            background-color: #1e1e1e;
            border-top: 1px solid #3e3e42;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .shell-header {
            height: 30px;
            background-color: #2d2d30;
            border-bottom: 1px solid #3e3e42;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 15px;
            font-size: 13px;
            color: #cccccc;
        }
        
        .shell-title {
            font-weight: 500;
        }
        
        .shell-close-btn {
            background: none;
            border: none;
            color: #cccccc;
            cursor: pointer;
            padding: 4px;
            border-radius: 3px;
            font-size: 16px;
            line-height: 1;
        }
        
        .shell-close-btn:hover {
            background-color: #3e3e42;
        }
        
        .shell-output {
            flex: 1;
            overflow-y: auto;
            padding: 10px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 13px;
            color: #d4d4d4;
            white-space: pre-wrap;
            word-wrap: break-word;
        }
        
        .shell-input-container {
            height: 40px;
            background-color: #2d2d30;
            border-top: 1px solid #3e3e42;
            display: flex;
            align-items: center;
            padding: 0 10px;
        }
        
        .shell-input {
            flex: 1;
            height: 28px;
            background-color: #1e1e1e;
            border: 1px solid #3e3e42;
            border-radius: 3px;
            color: #d4d4d4;
            padding: 0 10px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 13px;
            outline: none;
        }
        
        .shell-input:focus {
            border-color: #007acc;
        }
        
        .send-command-btn {
            margin-left: 10px;
            padding: 6px 15px;
            background-color: #007acc;
            border: none;
            border-radius: 3px;
            color: white;
            font-size: 13px;
            cursor: pointer;
        }
        
        .send-command-btn:hover {
            background-color: #005a9e;
        }
        
        /* 确保编辑器容器可以适应Shell调试区 */
        .editor-container {
            position: relative;
        }
        
        /* Shell图标样式 */
        #shell-toggle-btn {
            font-size: 16px;
        }
        
        </style>
    </head>
<body>
    <!-- 主容器 -->
    <div class="main-container">
        <!-- 左侧目录树 -->
        <div class="sidebar">
            <div class="sidebar-header">
                <h3>文件资源管理器</h3>
                <div class="sidebar-actions">
                    <span id="connection-status" class="connection-indicator" title="未连接">●</span>
                    <button id="shell-toggle-btn" class="refresh-btn" title="打开/关闭Shell调试区">⌨️</button>
            <button id="refresh-file-tree-btn" class="refresh-btn" title="刷新">↻</button>
                    <button class="collapse-btn" title="折叠所有目录">⇓</button>
                </div>
            </div>
            <div class="file-tree">
                <!-- 文件树内容将通过JavaScript动态生成 -->
            </div>
        </div>

        <!-- 右侧编辑窗口 -->
        <div class="editor-container">
            <!-- 标签栏 -->
            <div class="tabs-container">
                <div class="tabs" id="tabs-container">
                    <!-- 标签内容将通过JavaScript动态生成 -->
                </div>
                <div class="tabs-actions">
                    <button class="tab-action-btn" id="new-file-btn" title="新建文件">+</button>
                </div>
            </div>
            <!-- 移除了显示文件路径的头部区域 -->
            <div class="editor-content">
                <div class="editor-empty" id="editor-empty">
                    选择文件以进行编辑
                </div>
                <textarea class="code-editor" id="code-editor" style="display: none;"></textarea>
            </div>
            <!-- Shell调试区 -->
            <div id="shell-container" class="shell-container" style="display: none;">
                <div class="shell-header">
                    <span class="shell-title">Shell调试区</span>
                    <div style="display: flex; gap: 5px;">
                        <button id="clear-shell-output-btn" class="shell-close-btn" title="清空输出">🗑️</button>
                        <button id="reconnect-shell-btn" class="shell-close-btn" title="重新连接">🔄</button>
                        <button id="close-shell-btn" class="shell-close-btn" title="关闭Shell调试区">✕</button>
                    </div>
                </div>
                <div class="shell-output" id="shell-output"></div>
                <div class="shell-input-container">
                    <input type="text" id="shell-input" class="shell-input" placeholder="输入命令...">
                    <button id="send-command-btn" class="send-command-btn" title="发送命令">发送</button>
                </div>
            </div>
            <div class="editor-footer">
                <span id="file-info">--</span>
            </div>
        </div>
    </div>

    <!-- 右键菜单 -->
    <div class="context-menu" id="context-menu">
        <div class="context-menu-item" data-action="new-file">新建文件</div>
        <div class="context-menu-item" data-action="new-folder">新建文件夹</div>
        <div class="context-menu-item" data-action="rename">重命名</div>
        <div class="context-menu-item" data-action="delete">删除</div>
        <div class="context-menu-divider"></div>
        <div class="context-menu-item" data-action="upload">上传</div>
        <div class="context-menu-item" data-action="download">下载</div>
    </div>
    
    <!-- 标签右键菜单 -->
    <div class="context-menu" id="tab-context-menu">
        <div class="context-menu-item" data-action="close">关闭</div>
        <div class="context-menu-item" data-action="close-others">关闭其他</div>
        <div class="context-menu-item" data-action="close-right">关闭右侧标签</div>
        <div class="context-menu-item" data-action="close-saved">关闭已保存</div>
        <div class="context-menu-item" data-action="close-all">全部关闭</div>
    </div>

    <script>
        // 全局变量
        let rpcClient = null;
        let luaRpc = null;
        let fsRpc = null;
        let currentPath = ".";
        let selectedNode = null;
        let isConnected = false;
        let fileTree = {};
        let openTabs = []; // 存储打开的标签
        let activeTabPath = null; // 当前激活的标签路径
        let expandedDirectories = new Set(); // 存储所有展开的目录路径
        
        // Shell命令历史相关变量
        let commandHistory = []; // 存储命令历史
        let historyIndex = -1; // 当前历史索引
        let currentInput = ''; // 存储当前输入

        // DOM元素
        const connectionStatus = document.getElementById('connection-status');
        const fileTreeContainer = document.querySelector('.file-tree');
        const refreshBtn = document.getElementById('refresh-file-tree-btn');
        const collapseBtn = document.querySelector('.collapse-btn');
        const editorEmpty = document.getElementById('editor-empty');
        const codeEditor = document.getElementById('code-editor');
        // 移除了currentFile元素引用
        const fileInfo = document.getElementById('file-info');
        const contextMenu = document.getElementById('context-menu');
        const tabsContainer = document.getElementById('tabs-container');
        const newFileBtn = document.getElementById('new-file-btn');
        let tabContextMenu = null; // 标签右键菜单，稍后初始化
        
        // Shell相关元素
        const shellToggleBtn = document.getElementById('shell-toggle-btn');
        const shellContainer = document.getElementById('shell-container');
        const closeShellBtn = document.getElementById('close-shell-btn');
        const shellOutput = document.getElementById('shell-output');
        const shellInput = document.getElementById('shell-input');
        const sendCommandBtn = document.getElementById('send-command-btn');
        
        // Shell客户端实例
        let shellClient = null;

        // 初始化Shell客户端
        function initShellClient() {
            if (shellClient) {
                return;
            }
            
            // 加载shell.js文件
            loadScript('../javascript/shell.js').then(() => {
                if (typeof window.ShellClient !== 'undefined') {
                    // 创建Shell客户端实例 - 动态使用当前页面的主机名，固定端口9090
                    const currentHost = window.location.hostname;
                    const socketAddress = `${currentHost}:9090`;
                    
                    shellClient = new window.ShellClient(socketAddress, appendShellOutput);
                    
                    // 尝试连接
                    shellClient.connect();
                    
                    appendShellOutput(`Shell客户端已初始化，尝试连接到${socketAddress}...\n`);
                } else {
                    console.error('ShellClient未定义，无法初始化Shell客户端');
                    appendShellOutput('错误：无法加载Shell客户端\n');
                }
            }).catch(error => {
                console.error('加载shell.js失败:', error);
                appendShellOutput('错误：加载Shell客户端脚本失败\n');
            });
        }
        
        // 在Shell输出区添加内容，支持ANSI颜色转义序列
        function appendShellOutput(content) {
            // 解析ANSI颜色转义序列并转换为HTML
            const formattedContent = parseAnsiEscapeCodes(content);
            
            // 创建临时div元素来处理HTML内容
            const tempDiv = document.createElement('div');
            tempDiv.innerHTML = formattedContent;
            
            // 将所有子节点添加到shellOutput
            while (tempDiv.firstChild) {
                shellOutput.appendChild(tempDiv.firstChild);
            }
            
            shellOutput.scrollTop = shellOutput.scrollHeight;
        }
        
        // 解析ANSI转义序列，转换为HTML/CSS样式
        function parseAnsiEscapeCodes(text) {
            // 基本的ANSI颜色映射
            const colorMap = {
                '0': 'color: inherit;',      // 重置
                '30': 'color: #000000;',     // 黑色
                '31': 'color: #ff0000;',     // 红色
                '32': 'color: #00ff00;',     // 绿色
                '33': 'color: #ffff00;',     // 黄色
                '34': 'color: #0000ff;',     // 蓝色
                '35': 'color: #ff00ff;',     // 洋红色
                '36': 'color: #00ffff;',     // 青色
                '37': 'color: #ffffff;',     // 白色
                '90': 'color: #808080;',     // 暗灰色
                '91': 'color: #ff8080;',     // 亮红色
                '92': 'color: #80ff80;',     // 亮绿色
                '93': 'color: #ffff80;',     // 亮黄色
                '94': 'color: #8080ff;',     // 亮蓝色
                '95': 'color: #ff80ff;',     // 亮洋红色
                '96': 'color: #80ffff;',     // 亮青色
                '97': 'color: #ffffff;',     // 亮白色
                '40': 'background-color: #000000;', // 黑色背景
                '41': 'background-color: #ff0000;', // 红色背景
                '42': 'background-color: #00ff00;', // 绿色背景
                '43': 'background-color: #ffff00;', // 黄色背景
                '44': 'background-color: #0000ff;', // 蓝色背景
                '45': 'background-color: #ff00ff;', // 洋红色背景
                '46': 'background-color: #00ffff;', // 青色背景
                '47': 'background-color: #ffffff;', // 白色背景
                '100': 'background-color: #808080;', // 暗灰色背景
                '101': 'background-color: #ff8080;', // 亮红色背景
                '102': 'background-color: #80ff80;', // 亮绿色背景
                '103': 'background-color: #ffff80;', // 亮黄色背景
                '104': 'background-color: #8080ff;', // 亮蓝色背景
                '105': 'background-color: #ff80ff;', // 亮洋红色背景
                '106': 'background-color: #80ffff;', // 亮青色背景
                '107': 'background-color: #ffffff;'  // 亮白色背景
            };
            
            // 转义HTML特殊字符
            text = text
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;');
            
            // 处理ANSI转义序列
            let result = '';
            let i = 0;
            const ansiRegex = /\x1b\[(\d+(?:;\d+)*)m/g;
            
            let match;
            let lastIndex = 0;
            while ((match = ansiRegex.exec(text)) !== null) {
                // 添加匹配前的文本
                result += text.substring(lastIndex, match.index);
                
                // 处理ANSI代码
                const codes = match[1].split(';');
                
                // 查找重置代码
                if (codes.includes('0')) {
                    result += '</span>';
                    // 检查是否有其他代码
                    const otherCodes = codes.filter(code => code !== '0');
                    if (otherCodes.length > 0) {
                        // 添加带有新样式的span
                        let style = '';
                        otherCodes.forEach(code => {
                            if (colorMap[code]) {
                                style += colorMap[code] + ' ';
                            }
                        });
                        result += `<span style="${style.trim()}">`;
                    }
                } else {
                    // 添加带有样式的span
                    let style = '';
                    codes.forEach(code => {
                        if (colorMap[code]) {
                            style += colorMap[code] + ' ';
                        }
                    });
                    result += `<span style="${style.trim()}">`;
                }
                
                lastIndex = match.index + match[0].length;
            }
            
            // 添加剩余的文本
            result += text.substring(lastIndex);
            
            // 确保所有打开的span标签都被关闭
            const openSpans = (result.match(/<span/g) || []).length;
            const closeSpans = (result.match(/<\/span/g) || []).length;
            const missingCloses = openSpans - closeSpans;
            if (missingCloses > 0) {
                result += '</span>'.repeat(missingCloses);
            }
            
            return result;
        }
        
        // 发送Shell命令
        function sendShellCommand() {
            const command = shellInput.value.trim();
            if (!command) return;
            
            appendShellOutput('> ' + command + '\n');
            
            // 将命令添加到历史记录中，避免重复添加相同的命令
            if (commandHistory.length === 0 || commandHistory[commandHistory.length - 1] !== command) {
                commandHistory.push(command);
                // 限制历史记录长度，保留最新的100条命令
                if (commandHistory.length > 100) {
                    commandHistory.shift();
                }
            }
            
            // 重置历史索引和当前输入
            historyIndex = -1;
            currentInput = '';
            
            shellInput.value = '';
            
            if (shellClient && shellClient.sendCommand) {
                const success = shellClient.sendCommand(command);
                if (!success) {
                    appendShellOutput('错误：发送命令失败，连接未建立\n');
                }
            } else {
                appendShellOutput('错误：Shell客户端未初始化\n');
            }
        }
        
        // 切换Shell调试区显示状态
        function toggleShellPanel() {
            if (shellContainer.style.display === 'none') {
                // 显示Shell调试区
                shellContainer.style.display = 'flex';
                
                // 如果Shell客户端未初始化，初始化它
                if (!shellClient) {
                    initShellClient();
                }
            } else {
                // 隐藏Shell调试区
                shellContainer.style.display = 'none';
            }
        }
        
        // 初始化RPC连接
        async function initRpc() {
            try {
                // 只初始化一次
                if (rpcClient && isConnected) {
                    console.log('RPC已经初始化，不需要重新连接');
                    return;
                }
                
                // 重置连接状态
                connectionStatus.textContent = '●';
                connectionStatus.title = '连接中...';
                connectionStatus.className = 'connection-indicator connecting';
                
                // 动态加载所需的JS文件
                await Promise.all([
                    loadScript('../javascript/rpc.js'),
                    loadScript('../javascript/fs.js')
                ]);
                
                // 检查是否成功加载了所需的类
                if (typeof window.RpcClient === 'undefined' || typeof window.LuaRpc === 'undefined' || typeof window.FsRpc === 'undefined') {
                    throw new Error('无法加载必要的RPC或文件系统库');
                }
                
                // 重置实例
                rpcClient = null;
                luaRpc = null;
                fsRpc = null;
                
                // 创建RPC客户端，确保使用正确的URL格式
                console.log('创建RPC客户端...');
                // 使用当前页面的主机名，固定端口8080
                let serverUrl = `${window.location.hostname}:8080`;
                if (!serverUrl.startsWith('ws://') && !serverUrl.startsWith('wss://')) {
                    serverUrl = 'ws://' + serverUrl;
                }
                
                rpcClient = new window.RpcClient(serverUrl);
                
                // 添加连接超时处理
                const connectPromise = rpcClient.connectRpc();
                const timeoutPromise = new Promise((_, reject) => {
                    setTimeout(() => reject(new Error('连接超时(30秒)')), 30000);
                });
                
                // 使用Promise.race处理超时
                await Promise.race([connectPromise, timeoutPromise]);
                
                // 确保WebSocket状态为OPEN
                if (!rpcClient.socket || rpcClient.socket.readyState !== WebSocket.OPEN) {
                    throw new Error('WebSocket连接已建立但状态不正确');
                }
                
                // 添加WebSocket连接状态监听
                if (rpcClient.socket) {
                    // 先移除可能存在的监听器
                    rpcClient.socket.onclose = null;
                    rpcClient.socket.onerror = null;
                    
                    // 添加新的监听器
                    rpcClient.socket.onclose = () => {
                        console.log('WebSocket连接已关闭');
                        handleDisconnection();
                    };
                    
                    rpcClient.socket.onerror = (error) => {
                        console.error('WebSocket连接错误:', error);
                        handleDisconnection();
                    };
                }
                
                // 创建Lua RPC实例
                luaRpc = new window.LuaRpc(rpcClient);
                // 添加重试机制，最多尝试3次
                let luaId = null;
                const maxRetries = 3;
                for (let retry = 1; retry <= maxRetries; retry++) {
                    try {
                        await luaRpc.create();
                        console.log('Lua环境初始化成功');
                        break;
                    } catch (e) {
                        if (retry === maxRetries) {
                            throw e;
                        }
                        console.log(`Lua环境初始化尝试${retry}失败，${maxRetries - retry}次重试中...`);
                        await new Promise(resolve => setTimeout(resolve, 1000));
                    }
                }
                
                // 创建文件系统RPC实例
                fsRpc = new window.FsRpc(luaRpc);
                console.log('文件系统RPC初始化成功');
                
                isConnected = true;
                connectionStatus.textContent = '●';
                connectionStatus.title = '已连接';
                connectionStatus.className = 'connection-indicator connected';
                
                // 加载文件树
                await loadFileTree();
                
            } catch (error) {
                console.error('RPC初始化失败:', error);
                connectionStatus.textContent = '●';
                connectionStatus.title = `连接失败 - ${error.message}`;
                connectionStatus.className = 'connection-indicator';
                // 清理资源
                handleDisconnection();
            }
        }
        
        // 处理连接断开
        function handleDisconnection() {
            isConnected = false;
            fsRpc = null;
            connectionStatus.textContent = '●';
            connectionStatus.title = '已断开';
            connectionStatus.className = 'connection-indicator';
            console.log('RPC连接已断开，清理资源完成');
        }
        
        // 检查文件系统RPC是否可用
        function checkFsRpc() {
            // 添加详细的调试信息，查看每个变量的状态
            console.log(`checkFsRpc: isConnected=${isConnected}, fsRpc=${!!fsRpc}`);
            
            // 检查连接状态和fsRpc实例
            if (!isConnected) {
                console.error('checkFsRpc失败: RPC连接已断开');
                return false;
            }
            
            if (!fsRpc) {
                console.error('checkFsRpc失败: fsRpc实例不存在');
                return false;
            }
            
            // 检查fsRpc实例的核心方法是否存在
            if (typeof fsRpc.listDirItem !== 'function') {
                console.error('checkFsRpc失败: fsRpc缺少必要的方法');
                return false;
            }
            
            console.log('checkFsRpc通过: RPC连接和fsRpc实例正常');
            return true;
        }
        
        // 动态加载JavaScript文件
        function loadScript(src) {
            return new Promise((resolve, reject) => {
                const script = document.createElement('script');
                script.src = src;
                script.onload = resolve;
                script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
                document.head.appendChild(script);
            });
        }

        // 加载文件树
        async function loadFileTree() {
            try {
                // 如果连接不可用，尝试重新连接
                if (!isConnected) {
                    console.log('连接已断开，尝试重新连接...');
                    try {
                        await initRpc();
                    } catch (reconnectError) {
                        console.error('重新连接失败:', reconnectError);
                        // 即使重新连接失败，也要继续执行刷新操作
                    }
                }
                
                // 保存当前展开的目录状态
                const currentExpandedDirs = new Set(expandedDirectories);
                
                fileTreeContainer.innerHTML = '';
                fileTree = {};
                
                // 加载根目录
                await loadDirectory('/', fileTreeContainer);
                
                // 恢复展开状态
                expandDirectories(currentExpandedDirs);
            } catch (error) {
                console.error('加载文件树失败:', error);
                fileTreeContainer.innerHTML = `<div class="tree-node">加载失败: ${error.message}</div>`;
            }
        }

        // 折叠所有目录
        function collapseAllDirectories() {
            try {
                // 清除所有展开状态记录
                expandedDirectories.clear();
                
                // 找到所有展开的目录并折叠它们
                document.querySelectorAll('.expand-icon.expanded').forEach(icon => {
                    icon.classList.remove('expanded');
                    const nodeDiv = icon.parentElement;
                    const childrenContainer = nodeDiv.nextElementSibling;
                    if (childrenContainer && childrenContainer.className === 'children-container') {
                        childrenContainer.style.display = 'none';
                    }
                });
            } catch (error) {
                console.error('折叠所有目录失败:', error);
            }
        }

        // 加载目录内容
        async function loadDirectory(path, parentElement, parentNode = null) {
            try {
                // 添加调试日志
                console.log(`调用loadDirectory，路径: ${path}, 父节点: ${parentNode}`);
                
                // 验证参数有效性
                if (!path) {
                    console.error('loadDirectory失败: 路径为空');
                    if (parentElement) {
                        parentElement.innerHTML = `<div class="tree-node">错误: 路径不能为空</div>`;
                    }
                    return;
                }
                
                // 检查RPC连接状态
                const rpcStatus = checkFsRpc();
                console.log(`loadDirectory RPC状态检查结果: ${rpcStatus}`);
                
                if (!rpcStatus) {
                    // 如果连接不可用，但UI已经显示连接正常，尝试重新初始化
                    if (connectionStatus.className.includes('connected')) {
                        console.log(`RPC状态与UI显示不一致，尝试重新初始化...`);
                        try {
                            await initRpc();
                            
                            // 重新检查连接状态
                            if (!checkFsRpc()) {
                                console.error(`重新初始化后RPC仍然不可用`);
                                if (parentElement) {
                                    parentElement.innerHTML = `<div class="tree-node">错误: RPC连接不可用，请刷新页面</div>`;
                                }
                                return;
                            }
                        } catch (reinitError) {
                            console.error(`重新初始化RPC失败:`, reinitError);
                            if (parentElement) {
                                parentElement.innerHTML = `<div class="tree-node">错误: 重新连接失败</div>`;
                            }
                            return;
                        }
                    } else {
                        // 如果UI显示连接已断开，显示错误信息
                        if (parentElement) {
                            parentElement.innerHTML = `<div class="tree-node">错误: 请先连接服务器</div>`;
                        }
                        return;
                    }
                }
                
                // 使用listDirItem方法获取目录项
                console.log(`调用fsRpc.listDirItem，路径: ${path}`);
                let entries;
                try {
                    entries = await fsRpc.listDirItem(path);
                    console.log(`listDirItem返回结果:`, entries);
                } catch (listError) {
                    console.error(`listDirItem调用失败:`, listError);
                    if (parentElement) {
                        parentElement.innerHTML = `<div class="tree-node">错误: 无法读取目录内容</div>`;
                    }
                    return;
                }
                
                // 先按类型排序（目录在前），再按名称字母排序
                entries.sort((a, b) => {
                    // 目录排在文件前面
                    if (a.type === 'dir' && b.type !== 'dir') {
                        return -1;
                    }
                    if (a.type !== 'dir' && b.type === 'dir') {
                        return 1;
                    }
                    // 类型相同时按名称字母排序
                    return a.name.localeCompare(b.name);
                });
                
                // 创建目录节点
                for (const entry of entries) {
                    // 构建节点路径，确保根目录下的子目录以"/"开头
                    let nodePath;
                    if (path === '.' || path === '/') {
                        nodePath = `/${entry.name}`; // 根目录下的子目录路径以"/"开头
                    } else if (path.endsWith('/')) {
                        nodePath = `${path}${entry.name}`;
                    } else {
                        nodePath = `${path}/${entry.name}`;
                    }
                    
                    const nodeDiv = document.createElement('div');
                    nodeDiv.className = `tree-node ${entry.type === 'dir' ? 'folder' : 'file'}`;
                    nodeDiv.dataset.path = nodePath;
                    nodeDiv.dataset.type = entry.type;
                    
                    // 保存节点信息
                    fileTree[nodePath] = {
                        name: entry.name,
                        type: entry.type,
                        path: nodePath,
                        parent: parentNode,
                        element: nodeDiv
                    };
                    
                    // 目录节点添加展开图标
                    if (entry.type === 'dir') {
                        const expandIcon = document.createElement('span');
                        expandIcon.className = 'expand-icon';
                        nodeDiv.appendChild(expandIcon);
                          
                        // 展开/折叠事件 - 箭头图标，切换展开状态
                        expandIcon.addEventListener('click', (e) => {
                            e.stopPropagation(); // 阻止事件冒泡到父元素
                            toggleDirectory(nodePath);
                        });
                    } else {
                        // 文件节点添加缩进占位符
                        const indentPlaceholder = document.createElement('span');
                        indentPlaceholder.className = 'tree-indent';
                        nodeDiv.appendChild(indentPlaceholder);
                    }
                    
                    // 添加图标
                    const icon = document.createElement('span');
                    icon.className = 'icon';
                    // 根据文件类型显示不同的图标
                    if (entry.type === 'dir') {
                        icon.textContent = '📁';
                    } else if (entry.type === 'file') {
                        icon.textContent = '📄';
                    } else if (entry.type === 'dev') {
                        icon.textContent = '⚙️';
                    } else {
                        icon.textContent = '❓';
                    }
                    nodeDiv.appendChild(icon);
                    
                    // 添加名称和大小信息
                    const nameSpan = document.createElement('span');
                    nameSpan.textContent = entry.name;
                    nodeDiv.appendChild(nameSpan);
                    
                    // 对于文件，显示大小信息
                    if (entry.type !== 'dir' && entry.size !== undefined) {
                        const sizeSpan = document.createElement('span');
                        sizeSpan.className = 'file-size';
                        
                        // 格式化文件大小
                        let sizeText = '';
                        if (entry.size < 1024) {
                            sizeText = `${entry.size} B`;
                        } else if (entry.size < 1024 * 1024) {
                            sizeText = `${(entry.size / 1024).toFixed(1)} KB`;
                        } else if (entry.size < 1024 * 1024 * 1024) {
                            sizeText = `${(entry.size / (1024 * 1024)).toFixed(1)} MB`;
                        } else {
                            sizeText = `${(entry.size / (1024 * 1024 * 1024)).toFixed(1)} GB`;
                        }
                        
                        sizeSpan.textContent = sizeText;
                        nodeDiv.appendChild(sizeSpan);
                    }
                    
                    // 添加点击事件 - 实现点击整行都能切换目录展开/折叠状态
                        if (entry.type === 'dir') {
                            // 目录节点点击事件 - 不管展开还是折叠，点击整行都切换状态
                            nodeDiv.addEventListener('click', () => {
                                selectNode(nodeDiv);  // 先选择节点
                                toggleDirectory(nodePath);  // 然后切换展开/折叠状态
                            });
                        } else {
                            // 文件节点点击选择并打开
                            nodeDiv.addEventListener('click', () => selectNode(nodeDiv));
                        }
                    
                    // 添加右键菜单事件
                    nodeDiv.addEventListener('contextmenu', (e) => {
                        e.preventDefault();
                        showContextMenu(e, nodePath);
                    });
                    
                    // 先将nodeDiv添加到父元素
                    parentElement.appendChild(nodeDiv);
                    
                    // 对于目录节点，在添加到DOM后创建子节点容器
                    if (entry.type === 'dir') {
                        const childrenContainer = document.createElement('div');
                        childrenContainer.className = 'children-container';
                        childrenContainer.style.display = 'none';
                        // 将子容器作为下一个元素插入到nodeDiv后面
                        parentElement.insertBefore(childrenContainer, nodeDiv.nextSibling);
                    }
                }
            } catch (error) {
                console.error(`加载目录 ${path} 失败:`, error);
                const errorNode = document.createElement('div');
                errorNode.className = 'tree-node';
                errorNode.style.color = '#f44336';
                errorNode.textContent = `加载失败: ${error.message}`;
                parentElement.appendChild(errorNode);
            }
        }

        // 切换目录展开/折叠 - 确保子节点正确显示和隐藏
        async function toggleDirectory(path) {
            try {
                // 尝试获取节点
                let node = fileTree[path];
                
                // 验证节点是否存在且为目录
                if (!node || node.type !== 'dir') {
                    console.error(`路径不是目录或不存在: ${path}`);
                    return;
                }
                
                const expandIcon = node.element.querySelector('.expand-icon');
                const childrenContainer = node.element.nextElementSibling;
                
                // 检查当前展开状态
                const isExpanded = expandIcon.classList.contains('expanded');
                
                if (!isExpanded) {
                    // 展开目录
                    expandIcon.classList.add('expanded');
                    childrenContainer.style.display = 'block';
                    expandedDirectories.add(path); // 记录展开的目录
                    
                    // 如果子节点为空，加载目录内容
                    if (childrenContainer.children.length === 0) {
                        try {
                            // 调用loadDirectory加载目录内容
                            await loadDirectory(node.path, childrenContainer, node.path);
                        } catch (error) {
                            console.error(`加载目录 ${node.path} 失败:`, error);
                        }
                    }
                } else {
                    // 折叠目录 - 只隐藏子节点容器，不删除任何内容
                    expandIcon.classList.remove('expanded');
                    childrenContainer.style.display = 'none';
                    expandedDirectories.delete(path); // 移除折叠的目录
                }
            } catch (error) {
                console.error(`切换目录展开状态失败: ${error.message}`);
            }
        }
        
        // 批量展开目录
        async function expandDirectories(directories) {
            // 延迟执行以确保DOM已经完全渲染
            setTimeout(async () => {
                for (const path of directories) {
                    if (fileTree[path] && fileTree[path].type === 'dir') {
                        const node = fileTree[path];
                        const expandIcon = node.element.querySelector('.expand-icon');
                        const childrenContainer = node.element.nextElementSibling;
                        
                        expandIcon.classList.add('expanded');
                        childrenContainer.style.display = 'block';
                        
                        // 如果子节点为空，加载目录内容
                        if (childrenContainer.children.length === 0) {
                            try {
                                await loadDirectory(node.path, childrenContainer, node.path);
                            } catch (error) {
                                console.error(`恢复展开目录 ${node.path} 失败:`, error);
                            }
                        }
                    }
                }
            }, 10);
        }

        // 选择节点
        async function selectNode(nodeElement) {
            // 取消之前的选择
            if (selectedNode) {
                selectedNode.classList.remove('selected');
            }
            
            // 设置新的选择
            selectedNode = nodeElement;
            selectedNode.classList.add('selected');
            
            const path = nodeElement.dataset.path;
            const type = nodeElement.dataset.type;
            
            if (type === 'file') {
                // 打开文件
                await openFile(path);
            } else {
                // 选择目录时，不改变当前打开的文件内容
                // 不更新文件路径显示（已移除）
                // 不改变编辑器的显示状态
                // fileInfo可以保持更新，显示当前选中的目录
                fileInfo.textContent = `目录: ${path}`;
            }
        }

        // 添加标签
        function addTab(path, content = '') {
            // 检查文件是否已经打开
            const existingTab = openTabs.find(tab => tab.path === path);
            if (existingTab) {
                // 如果文件已打开，切换到该标签
                activateTab(path);
                return;
            }

            // 获取文件名
            const fileName = path.split('/').pop();
            
            // 创建新标签对象，包含完整状态信息
            const tab = {
                path: path,
                content: content,
                scrollTop: 0,        // 滚动位置
                selectionStart: 0,   // 光标开始位置
                selectionEnd: 0,     // 光标结束位置
                element: null,
                isModified: false    // 文件是否被修改但未保存
            };
            openTabs.push(tab);
            
            // 创建标签元素
            const tabElement = document.createElement('div');
            tabElement.className = 'tab';
            tabElement.dataset.path = path;
            tabElement.innerHTML = `
                <span class="tab-name">${fileName}</span>
                <span class="tab-modified-indicator"></span>
                <span class="tab-close" title="关闭标签">×</span>
            `;
            
            // 保存标签元素引用
            tab.element = tabElement;
            
            // 添加点击事件
            tabElement.addEventListener('click', (e) => {
                if (!e.target.classList.contains('tab-close')) {
                    activateTab(path);
                }
            });
            
            // 添加关闭事件
            const closeBtn = tabElement.querySelector('.tab-close');
            closeBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                closeTab(path);
            });
            
            // 添加到标签容器
            tabsContainer.appendChild(tabElement);
            
            // 激活新标签
            activateTab(path);
        }

        // 激活标签
        async function activateTab(path) {
            // 先保存当前激活标签的完整状态
            saveActiveTabState();
            
            // 更新激活状态
            document.querySelectorAll('.tab').forEach(tab => {
                if (tab.dataset.path === path) {
                    tab.classList.add('active');
                } else {
                    tab.classList.remove('active');
                }
            });
            
            // 更新当前激活的标签路径
            activeTabPath = path;
            
            // 加载标签内容
            const tab = openTabs.find(tab => tab.path === path);
            if (tab) {
                // 读取文件内容（如果内容为空或需要重新加载）
                if (!tab.content) {
                    if (checkFsRpc()) {
                        try {
                            tab.content = await fsRpc.readFile(path);
                        } catch (error) {
                            console.error(`读取文件 ${path} 失败:`, error);
                            tab.content = '';
                        }
                    }
                }
                
                // 显示文件内容
                editorEmpty.style.display = 'none';
                codeEditor.style.display = 'block';
                
                // 设置编辑器内容和恢复状态
                restoreTabState(tab);
                
                // 更新文件信息
                if (checkFsRpc()) {
                    try {
                        const stat = await fsRpc.stat(path);
                        const fileSize = tab.content.length;
                        fileInfo.textContent = `文件: ${path} (${fileSize} 字节)`;
                    } catch (error) {
                        console.error(`获取文件信息 ${path} 失败:`, error);
                        fileInfo.textContent = `文件: ${path}`;
                    }
                }
                
                // 高亮文件树中对应的节点
                highlightFileInTree(path);
            }
        }
        
        // 保存当前激活标签的状态
        function saveActiveTabState() {
            if (activeTabPath && codeEditor.style.display !== 'none') {
                const activeTab = openTabs.find(tab => tab.path === activeTabPath);
                if (activeTab) {
                    // 保存内容
                    activeTab.content = codeEditor.value;
                    // 保存滚动位置
                    activeTab.scrollTop = codeEditor.scrollTop;
                    // 保存光标位置
                    activeTab.selectionStart = codeEditor.selectionStart;
                    activeTab.selectionEnd = codeEditor.selectionEnd;
                }
            }
        }
        
        // 恢复标签状态
        function restoreTabState(tab) {
            // 先保存要恢复的状态
            const savedScrollTop = tab.scrollTop || 0;
            const savedSelectionStart = tab.selectionStart || 0;
            const savedSelectionEnd = tab.selectionEnd || 0;
            
            // 先隐藏编辑器，避免用户看到滚动位置的变化
            codeEditor.style.visibility = 'hidden';
            codeEditor.style.display = 'block';
            
            // 使用requestAnimationFrame确保与浏览器渲染同步
            requestAnimationFrame(() => {
                // 设置内容
                codeEditor.value = tab.content || '';
                
                // 强制浏览器计算滚动高度
                const contentHeight = codeEditor.scrollHeight;
                const clientHeight = codeEditor.clientHeight;
                
                // 安全地恢复滚动位置
                const safeScrollTop = Math.min(savedScrollTop, contentHeight - clientHeight);
                codeEditor.scrollTop = safeScrollTop;
                
                // 恢复光标位置
                if (codeEditor.value.length > 0) {
                    const start = Math.min(savedSelectionStart, codeEditor.value.length);
                    const end = Math.min(savedSelectionEnd, codeEditor.value.length);
                    codeEditor.setSelectionRange(start, end);
                }
                
                // 聚焦编辑器
                codeEditor.focus();
                
                // 确保内容完全渲染后再显示编辑器
                requestAnimationFrame(() => {
                    codeEditor.style.visibility = 'visible';
                    
                    // 对于长内容，再进行一次确认性恢复
                    if (contentHeight > clientHeight * 2) {
                        requestAnimationFrame(() => {
                            const safeScrollTop = Math.min(savedScrollTop, codeEditor.scrollHeight - codeEditor.clientHeight);
                            codeEditor.scrollTop = safeScrollTop;
                        });
                    }
                });
            });
        }

        // 关闭标签
        function closeTab(path) {
            // 找到标签索引
            const tabIndex = openTabs.findIndex(tab => tab.path === path);
            if (tabIndex === -1) return;
            
            // 移除标签元素
            const tab = openTabs[tabIndex];
            if (tab.element && tab.element.parentNode) {
                tab.element.parentNode.removeChild(tab.element);
            }
            
            // 从数组中移除
            openTabs.splice(tabIndex, 1);
            
            // 如果关闭的是当前激活的标签，激活下一个标签
            if (path === activeTabPath) {
                if (openTabs.length > 0) {
                    // 选择前一个标签或最后一个标签
                    const newActiveIndex = tabIndex > 0 ? tabIndex - 1 : openTabs.length - 1;
                    activateTab(openTabs[newActiveIndex].path);
                } else {
                    // 没有标签了，显示空编辑器
                    activeTabPath = null;
                    // 不更新文件路径显示（已移除）
                    editorEmpty.style.display = 'flex';
                    codeEditor.style.display = 'none';
                    fileInfo.textContent = '--';
                    
                    // 取消文件树中的选择
                    if (selectedNode) {
                        selectedNode.classList.remove('selected');
                        selectedNode = null;
                    }
                }
            }
        }

        // 高亮文件树中的文件
        function highlightFileInTree(path) {
            // 取消之前的选择
            if (selectedNode) {
                selectedNode.classList.remove('selected');
            }
            
            // 查找对应的节点
            const node = fileTree[path];
            if (node && node.element) {
                selectedNode = node.element;
                selectedNode.classList.add('selected');
                
                // 滚动到节点
                if (selectedNode.scrollIntoView) {
                    selectedNode.scrollIntoView({ behavior: 'smooth', block: 'center' });
                }
            }
        }

        // 打开文件
        async function openFile(path) {
            try {
                if (!checkFsRpc()) return;
                // 读取文件内容
                const content = await fsRpc.readFile(path);
                
                // 使用标签打开文件
                addTab(path, content);
                
            } catch (error) {
                console.error(`打开文件 ${path} 失败:`, error);
                alert(`打开文件失败: ${error.message}`);
            }
        }

        // 保存文件
        async function saveFile() {
            if (!activeTabPath) {
                alert('请先选择要保存的文件');
                return;
            }
            
            // 查找当前激活的标签
            const tab = openTabs.find(tab => tab.path === activeTabPath);
            if (!tab) {
                alert('未找到对应的文件标签');
                return;
            }
            
            try {
                if (!checkFsRpc()) return;
                const content = codeEditor.value;
                
                // 写入文件
                await fsRpc.writeFile(activeTabPath, content);
                
                // 更新标签中的内容
                tab.content = content;
                
                // 设置文件为已保存状态
                tab.isModified = false;
                updateTabModifiedStatus(tab);
                
                // 更新文件信息
                const fileSize = content.length;
                fileInfo.textContent = `文件: ${activeTabPath} (${fileSize} 字节)`;
                
                // 可以添加一个临时的保存成功提示，而不是使用alert
                const saveStatus = document.createElement('div');
                saveStatus.className = 'save-status';
                saveStatus.textContent = '保存成功';
                document.body.appendChild(saveStatus);
                
                // 2秒后移除提示
                setTimeout(() => {
                    if (saveStatus.parentNode) {
                        saveStatus.parentNode.removeChild(saveStatus);
                    }
                }, 2000);
                
            } catch (error) {
                console.error(`保存文件 ${activeTabPath} 失败:`, error);
                alert(`保存文件失败: ${error.message}`);
            }
        }

        // 显示右键菜单
        function showContextMenu(event, path) {
            // 更新菜单位置
            contextMenu.style.left = `${event.clientX}px`;
            contextMenu.style.top = `${event.clientY}px`;
            contextMenu.style.display = 'block';
            
            // 保存当前操作的路径
            contextMenu.dataset.path = path;
        }

        // 创建进度指示器模态框
        function createProgressModal(title) {
            const modal = document.createElement('div');
            modal.className = 'progress-modal';
            modal.innerHTML = `
                <div class="progress-modal-content">
                    <h3>${title}</h3>
                    <div class="progress-message"></div>
                    <div class="progress-bar-container">
                        <div class="progress-bar"></div>
                    </div>
                </div>
            `;
            
            // 添加样式
            const style = document.createElement('style');
            style.textContent = `
                .progress-modal {
                    position: fixed;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    background-color: rgba(0, 0, 0, 0.5);
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    z-index: 1000;
                }
                .progress-modal-content {
                    background-color: #2c2c2c;
                    padding: 20px;
                    border-radius: 5px;
                    min-width: 300px;
                    color: white;
                }
                .progress-modal-content h3 {
                    margin-top: 0;
                    margin-bottom: 10px;
                }
                .progress-message {
                    margin-bottom: 10px;
                    font-size: 14px;
                }
                .progress-bar-container {
                    width: 100%;
                    height: 20px;
                    background-color: #444;
                    border-radius: 10px;
                    overflow: hidden;
                }
                .progress-bar {
                    height: 100%;
                    background-color: #4CAF50;
                    transition: width 0.3s;
                }
            `;
            document.head.appendChild(style);
            
            return modal;
        }
        
        // 更新进度指示器
        function updateProgressModal(modal, message, progress) {
            const messageElement = modal.querySelector('.progress-message');
            const progressBar = modal.querySelector('.progress-bar');
            
            if (messageElement) {
                messageElement.textContent = message;
            }
            
            if (progressBar) {
                progressBar.style.width = `${progress * 100}%`;
            }
        }
        
        // 读取文件内容并上传
        async function readAndUploadFile(file, targetPath) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.onload = async (event) => {
                    try {
                        // 确保内容是字符串类型
                        const fileContent = typeof event.target.result === 'string' ? event.target.result : String(event.target.result);
                        // 上传文件
                        await fsRpc.writeFile(targetPath, fileContent);
                        resolve();
                    } catch (error) {
                        reject(new Error(`上传文件 ${file.name} 失败: ${error.message}`));
                    }
                };
                reader.onerror = () => {
                    reject(new Error(`读取文件 ${file.name} 失败`));
                };
                
                // 根据文件类型选择读取方式
                if (file.type.includes('text') || file.name.match(/\.(txt|js|html|css|json|xml|md)$/i)) {
                    reader.readAsText(file);
                } else {
                    // 对于二进制文件，使用ArrayBuffer读取
                    reader.readAsArrayBuffer(file);
                }
            });
        }
        
        // 辅助函数：规范化文件路径，特别是在Windows系统上
        function normalizePath(path) {
            // 在Windows系统上，确保路径使用正斜杠作为分隔符
            return path.replace(/\\/g, '/');
        }
        
        // 下载目录
        async function downloadDirectory(path) {
            try {
                // 规范化路径
                path = normalizePath(path);
                
                // 显示进度指示器
                const progressModal = createProgressModal('正在准备下载...');
                document.body.appendChild(progressModal);
                
                // 获取目录名称和父目录路径
                const dirName = path.split('/').pop() || 'download';
                const zipFileName = `${dirName}.zip`;
                
                // 获取下载目录的父目录
                const parentPath = path.lastIndexOf('/') > 0 ? path.substring(0, path.lastIndexOf('/')) : '/';
                
                // 在同级目录下创建ZIP文件
                const tempZipPath = path.lastIndexOf('/') === 0 ? `/${zipFileName}` : `${parentPath}/${zipFileName}`;
                
                // 创建ZIP文件
                const zipObj = await fsRpc.zipCreate(tempZipPath);
                let zipClosed = false;
                
                try {
                    // 直接添加整个目录到ZIP文件
                    updateProgressModal(progressModal, `正在添加目录: ${path}`, 0.1);
                    
                    // 直接使用zipAddItem添加整个目录，格式为addItem(archiveName, srcPath, level)
                    // archiveName是ZIP中的目录名，srcPath是源目录路径，level是压缩级别
                    const success = await fsRpc.zipAddItem(zipObj, dirName, path, 6);
                    
                    if (!success) {
                        throw new Error(`添加目录到ZIP失败: ${path}`);
                    }
                    
                    updateProgressModal(progressModal, `目录内容添加完成`, 0.9);
                    
                    // 关闭ZIP文件
                    await fsRpc.zipClose(zipObj);
                    zipClosed = true;
                    
                    // 下载ZIP文件
                    updateProgressModal(progressModal, `正在下载ZIP文件: ${zipFileName}`, 0.95);
                    
                    // 读取ZIP文件内容
                    const zipContent = await fsRpc.readFile(tempZipPath, 'binary');
                    const blob = new Blob([zipContent], { type: 'application/zip' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = zipFileName;
                    a.style.display = 'none';
                    document.body.appendChild(a);
                    
                    // 使用setTimeout确保DOM已经更新
                    setTimeout(() => {
                        a.click();
                        document.body.removeChild(a);
                        URL.revokeObjectURL(url);
                        
                        // 移除进度指示器
                        document.body.removeChild(progressModal);
                    }, 100);
                    
                    console.log(`目录 ${dirName} 已成功打包为ZIP文件并开始下载`);
                } catch (error) {
                    // 发生错误时尝试删除临时ZIP文件
                    try {
                        // 使用fs.js中正确的unlink函数删除文件
                        await fsRpc.unlink(tempZipPath);
                        console.log(`错误时已删除临时ZIP文件: ${tempZipPath}`);
                    } catch (removeError) {
                        console.warn('清理临时ZIP文件失败:', removeError);
                    }
                    
                    throw error;
                } finally {
                    // 确保ZIP文件已经关闭（但不抛出异常，避免影响finally块执行）
                    try {
                        if (!zipClosed) {
                            await fsRpc.zipClose(zipObj);
                            zipClosed = true;
                        }
                    } catch (closeError) {
                        console.warn('关闭ZIP文件失败:', closeError);
                    }
                    
                    // 下载完成后保留临时ZIP文件
                    // 根据需求，不再自动删除生成的ZIP文件
                    console.log(`临时ZIP文件已保留: ${tempZipPath}`);
                }
            } catch (error) {
                console.error('下载目录失败:', error);
                alert(`下载目录失败: ${error.message}`);
                throw error;
            }
        }
        
        // 下载单个文件（用于单独文件下载）
        async function downloadSingleFile(filePath) {
            try {
                const content = await fsRpc.readFile(filePath, 'binary');
                const fileName = filePath.split('/').pop();
                const blob = new Blob([content], { type: 'application/octet-stream' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = fileName;
                a.style.display = 'none';
                document.body.appendChild(a);
                
                // 使用setTimeout确保DOM已经更新
                setTimeout(() => {
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                }, 100);
            } catch (error) {
                console.error(`下载文件 ${filePath} 失败:`, error);
                throw error;
            }
        }
        
        // 处理右键菜单操作
        async function handleContextMenuAction(action, path) {
            contextMenu.style.display = 'none';
            
            try {
                if (!checkFsRpc()) return;
                switch (action) {
                    case 'new-file': {
                        const fileName = prompt('请输入文件名:', 'newfile.txt');
                        if (!fileName) return;
                        
                        const newFilePath = path === '.' ? fileName : `${path}/${fileName}`;
                        
                        // 检查文件是否已存在
                        if (await fsRpc.exist(newFilePath)) {
                            alert('文件已存在');
                            return;
                        }
                        
                        // 创建空文件
                        await fsRpc.writeFile(newFilePath, '');
                        
                        // 刷新目录
                        if (path === '.') {
                            // 保存当前展开的目录状态
                            const currentExpandedDirs = new Set(expandedDirectories);
                            
                            // 重新加载根目录
                            fileTreeContainer.innerHTML = '';
                            fileTree = {};
                            await loadDirectory('/', fileTreeContainer);
                            
                            // 恢复展开状态
                            expandDirectories(currentExpandedDirs);
                        } else {
                            const parentNode = fileTree[path];
                            if (parentNode) {
                                const childrenContainer = parentNode.element.nextElementSibling;
                                const expandIcon = parentNode.element.querySelector('.expand-icon');
                                const wasExpanded = expandIcon.classList.contains('expanded');
                                
                                // 保存该目录下所有展开的子目录状态
                                const childExpandedDirs = new Set();
                                for (const dirPath of expandedDirectories) {
                                    if (dirPath.startsWith(path + '/')) {
                                        childExpandedDirs.add(dirPath);
                                    }
                                }
                                
                                childrenContainer.innerHTML = '';
                                await loadDirectory(path, childrenContainer, path);
                                
                                // 恢复之前的展开状态
                                if (wasExpanded) {
                                    expandIcon.classList.add('expanded');
                                    childrenContainer.style.display = 'block';
                                    // 恢复子目录的展开状态
                                    expandDirectories(childExpandedDirs);
                                }
                            }
                        }
                        break;
                    }
                    
                    case 'new-folder': {
                        const folderName = prompt('请输入文件夹名:', 'newfolder');
                        if (!folderName) return;
                        
                        const newFolderPath = path === '.' ? folderName : `${path}/${folderName}`;
                        
                        // 检查文件夹是否已存在
                        if (await fsRpc.exist(newFolderPath)) {
                            alert('文件夹已存在');
                            return;
                        }
                        
                        // 创建文件夹
                        await fsRpc.mkdir(newFolderPath);
                        
                        // 刷新目录
                        if (path === '.') {
                            // 保存当前展开的目录状态
                            const currentExpandedDirs = new Set(expandedDirectories);
                            
                            // 重新加载根目录
                            fileTreeContainer.innerHTML = '';
                            fileTree = {};
                            await loadDirectory('/', fileTreeContainer);
                            
                            // 恢复展开状态
                            expandDirectories(currentExpandedDirs);
                        } else {
                            const parentNode = fileTree[path];
                            if (parentNode) {
                                const childrenContainer = parentNode.element.nextElementSibling;
                                const expandIcon = parentNode.element.querySelector('.expand-icon');
                                const wasExpanded = expandIcon.classList.contains('expanded');
                                
                                // 保存该目录下所有展开的子目录状态
                                const childExpandedDirs = new Set();
                                for (const dirPath of expandedDirectories) {
                                    if (dirPath.startsWith(path + '/')) {
                                        childExpandedDirs.add(dirPath);
                                    }
                                }
                                
                                childrenContainer.innerHTML = '';
                                await loadDirectory(path, childrenContainer, path);
                                
                                // 恢复之前的展开状态
                                if (wasExpanded) {
                                    expandIcon.classList.add('expanded');
                                    childrenContainer.style.display = 'block';
                                    // 恢复子目录的展开状态
                                    expandDirectories(childExpandedDirs);
                                }
                            }
                        }
                        break;
                    }
                    
                    case 'rename': {
                        const node = fileTree[path];
                        if (!node) return;
                        
                        const newName = prompt('请输入新名称:', node.name);
                        if (!newName || newName === node.name) return;
                        
                        // 构建新路径
                        const parentPath = node.parent || '.';
                        const newPath = parentPath === '.' ? newName : `${parentPath}/${newName}`;
                        
                        // 检查是否已存在
                        if (await fsRpc.exist(newPath)) {
                            alert('名称已存在');
                            return;
                        }
                        
                        // 重命名
                        await fsRpc.rename(path, newPath);
                        
                        // 刷新目录
                        if (parentPath === '.') {
                            // 保存当前展开的目录状态
                            const currentExpandedDirs = new Set(expandedDirectories);
                            
                            // 重新加载根目录
                            fileTreeContainer.innerHTML = '';
                            fileTree = {};
                            await loadDirectory('/', fileTreeContainer);
                            
                            // 恢复展开状态
                            expandDirectories(currentExpandedDirs);
                        } else {
                            const parentNode = fileTree[parentPath];
                            if (parentNode) {
                                const childrenContainer = parentNode.element.nextElementSibling;
                                const expandIcon = parentNode.element.querySelector('.expand-icon');
                                const wasExpanded = expandIcon.classList.contains('expanded');
                                
                                // 保存该目录下所有展开的子目录状态
                                const childExpandedDirs = new Set();
                                for (const dirPath of expandedDirectories) {
                                    if (dirPath.startsWith(parentPath + '/')) {
                                        childExpandedDirs.add(dirPath);
                                    }
                                }
                                
                                childrenContainer.innerHTML = '';
                                await loadDirectory(parentPath, childrenContainer, parentPath);
                                
                                // 恢复之前的展开状态
                                if (wasExpanded) {
                                    expandIcon.classList.add('expanded');
                                    childrenContainer.style.display = 'block';
                                    // 恢复子目录的展开状态
                                    expandDirectories(childExpandedDirs);
                                }
                            }
                        }
                        break;
                    }
                    
                    case 'delete': {
                        if (!confirm(`确定要删除 ${path} 吗？`)) return;
                        
                        const node = fileTree[path];
                        if (!node) return;
                        
                        // 删除文件或目录
                        if (node.type === 'file') {
                            await fsRpc.unlink(path);
                        } else {
                            await fsRpc.remove(path);
                        }
                        
                        // 刷新目录
                        const parentPath = node.parent || '.';
                        if (parentPath === '.') {
                            // 保存当前展开的目录状态
                            const currentExpandedDirs = new Set(expandedDirectories);
                            
                            // 重新加载根目录
                            fileTreeContainer.innerHTML = '';
                            fileTree = {};
                            await loadDirectory('/', fileTreeContainer);
                            
                            // 恢复展开状态
                            expandDirectories(currentExpandedDirs);
                        } else {
                            const parentNode = fileTree[parentPath];
                            if (parentNode) {
                                const childrenContainer = parentNode.element.nextElementSibling;
                                const expandIcon = parentNode.element.querySelector('.expand-icon');
                                const wasExpanded = expandIcon.classList.contains('expanded');
                                
                                // 保存该目录下所有展开的子目录状态
                                const childExpandedDirs = new Set();
                                for (const dirPath of expandedDirectories) {
                                    if (dirPath.startsWith(parentPath + '/')) {
                                        childExpandedDirs.add(dirPath);
                                    }
                                }
                                
                                childrenContainer.innerHTML = '';
                                await loadDirectory(parentPath, childrenContainer, parentPath);
                                
                                // 恢复之前的展开状态
                                if (wasExpanded) {
                                    expandIcon.classList.add('expanded');
                                    childrenContainer.style.display = 'block';
                                    // 恢复子目录的展开状态
                                    expandDirectories(childExpandedDirs);
                                }
                            }
                        }
                        
                        // 如果删除的是当前选中的节点，清空编辑器
                        if (selectedNode && selectedNode.dataset.path === path) {
                            selectedNode = null;
                            // 不更新文件路径显示（已移除）
                            editorEmpty.style.display = 'flex';
                            codeEditor.style.display = 'none';
                            fileInfo.textContent = '--';
                        }
                        break;
                    }
                    
                    case 'upload': {
                        // 创建文件选择对话框，支持选择文件和目录
                        const input = document.createElement('input');
                        input.type = 'file';
                        input.webkitdirectory = true;  // 支持选择目录（Chrome）
                        input.directory = true;        // 支持选择目录（Firefox）
                        input.multiple = true;         // 支持选择多个文件/目录
                        input.style.display = 'none';
                         
                        // 监听文件选择事件
                        input.addEventListener('change', async (e) => {
                            const files = e.target.files;
                            if (!files || files.length === 0) return;
                             
                            try {
                                // 获取节点信息判断是文件还是目录
                                const node = fileTree[path];
                                let targetDir = path;
                                 
                                // 如果点击的是文件，上传到文件所在目录
                                if (node && node.type === 'file') {
                                    targetDir = node.parent || '.';
                                }
                                 
                                // 显示进度指示器
                                const progressModal = createProgressModal('正在上传...');
                                document.body.appendChild(progressModal);
                                let processedCount = 0;
                                 
                                // 处理选择的文件/目录
                                for (let i = 0; i < files.length; i++) {
                                    const file = files[i];
                                    // 获取相对路径（对于目录上传，会包含完整的相对路径结构）
                                    const relativePath = file.webkitRelativePath || file.name;
                                    // 构建目标路径
                                    const targetPath = targetDir === '.' ? relativePath : `${targetDir}/${relativePath}`;
                                    
                                    // 确保目标路径的目录结构存在
                                    // 提取目录部分（去掉文件名）
                                    const dirPath = targetPath.substring(0, targetPath.lastIndexOf('/'));
                                    // 如果目录路径不为空，则使用mkpath创建完整目录结构
                                    if (dirPath) {
                                        await fsRpc.mkpath(dirPath);
                                    }
                                     
                                    // 更新进度
                                    processedCount++;
                                    updateProgressModal(progressModal, `正在上传: ${file.name}`, processedCount / files.length);
                                     
                                    // 检查文件是否已存在
                                    if (await fsRpc.exist(targetPath)) {
                                        if (!confirm(`文件 ${file.name} 已存在，是否覆盖？`)) {
                                            continue;
                                        }
                                    }
                                     
                                    // 读取文件内容并上传
                                    await readAndUploadFile(file, targetPath);
                                }
                                 
                                // 移除进度指示器
                                document.body.removeChild(progressModal);
                                 
                                // 刷新目录
                                if (targetDir === '.') {
                                    const currentExpandedDirs = new Set(expandedDirectories);
                                    fileTreeContainer.innerHTML = '';
                                    fileTree = {};
                                    await loadDirectory('/', fileTreeContainer);
                                    expandDirectories(currentExpandedDirs);
                                } else {
                                    const parentNode = fileTree[targetDir];
                                    if (parentNode) {
                                        const childrenContainer = parentNode.element.nextElementSibling;
                                        const expandIcon = parentNode.element.querySelector('.expand-icon');
                                        const wasExpanded = expandIcon.classList.contains('expanded');
                                         
                                        const childExpandedDirs = new Set();
                                        for (const dirPath of expandedDirectories) {
                                            if (dirPath.startsWith(targetDir + '/')) {
                                                childExpandedDirs.add(dirPath);
                                            }
                                        }
                                         
                                        childrenContainer.innerHTML = '';
                                        await loadDirectory(targetDir, childrenContainer, targetDir);
                                         
                                        if (wasExpanded) {
                                            expandIcon.classList.add('expanded');
                                            childrenContainer.style.display = 'block';
                                            expandDirectories(childExpandedDirs);
                                        }
                                    }
                                }
                                
                                alert('上传完成！');
                            } catch (error) {
                                alert(`上传失败: ${error.message}`);
                                console.error('上传错误:', error);
                            }
                        });
                         
                        // 添加到文档并触发点击
                        document.body.appendChild(input);
                        input.click();
                        document.body.removeChild(input);
                        break;
                    }
                    
                    case 'download': {
                        const node = fileTree[path];
                        if (!node) return;
                         
                        try {
                            if (node.type === 'file') {
                                // 下载单个文件
                                const content = await fsRpc.readFile(path, 'binary');
                                const blob = new Blob([content], { type: 'application/octet-stream' });
                                const url = URL.createObjectURL(blob);
                                const a = document.createElement('a');
                                a.href = url;
                                a.download = node.name;
                                a.style.display = 'none';
                                document.body.appendChild(a);
                                a.click();
                                document.body.removeChild(a);
                                URL.revokeObjectURL(url);
                            } else {
                                // 下载目录
                                await downloadDirectory(path);
                            }
                        } catch (downloadError) {
                            alert(`下载失败: ${downloadError.message}`);
                        }
                        break;
                    }
                }
            } catch (error) {
                console.error(`执行操作 ${action} 失败:`, error);
                alert(`操作失败: ${error.message}`);
            }
        }

        // 事件监听器
        document.addEventListener('DOMContentLoaded', initRpc);
        
        refreshBtn.addEventListener('click', loadFileTree);
        
        // Shell相关事件监听器
        shellToggleBtn.addEventListener('click', toggleShellPanel);
        closeShellBtn.addEventListener('click', toggleShellPanel);
        sendCommandBtn.addEventListener('click', sendShellCommand);
        
        // 清空输出按钮事件
        document.getElementById('clear-shell-output-btn').addEventListener('click', () => {
            const shellOutput = document.getElementById('shell-output');
            shellOutput.textContent = '';
        });
        
        // 重新连接按钮事件
        document.getElementById('reconnect-shell-btn').addEventListener('click', () => {
            appendShellOutput('正在重新连接...');
            if (shellClient) {
                try {
                    // 断开现有连接
                    if (typeof shellClient.disconnect === 'function') {
                        shellClient.disconnect();
                    }
                } catch (e) {
                    console.error('断开连接失败:', e);
                }
                shellClient = null;
            }
            // 初始化新连接
            initShellClient();
        });
        
        // 键盘事件处理：Enter发送命令，上下键浏览历史命令
        shellInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') {
                sendShellCommand();
            } else if (e.key === 'ArrowUp') {
                // 向上键：显示上一条历史命令
                e.preventDefault(); // 阻止默认行为
                
                if (commandHistory.length === 0) return;
                
                // 如果是第一次按上键，保存当前输入
                if (historyIndex === -1) {
                    currentInput = shellInput.value;
                }
                
                // 移动到上一条命令
                if (historyIndex < commandHistory.length - 1) {
                    historyIndex++;
                    shellInput.value = commandHistory[commandHistory.length - 1 - historyIndex];
                }
            } else if (e.key === 'ArrowDown') {
                // 向下键：显示下一条历史命令
                e.preventDefault(); // 阻止默认行为
                
                if (historyIndex === -1) return;
                
                // 移动到下一条命令
                historyIndex--;
                
                if (historyIndex < 0) {
                    // 如果回到当前输入，显示保存的内容
                    shellInput.value = currentInput;
                    historyIndex = -1;
                } else {
                    shellInput.value = commandHistory[commandHistory.length - 1 - historyIndex];
                }
            }
        });
        
        // 连接状态指示器点击事件 - 连接失败时点击可重连
        connectionStatus.addEventListener('click', async () => {
            if (!isConnected) {
                console.log('用户点击连接状态指示器，尝试重新连接...');
                connectionStatus.title = '连接中...';
                connectionStatus.className = 'connection-indicator connecting';
                try {
                    await initRpc();
                } catch (reconnectError) {
                    console.error('重新连接失败:', reconnectError);
                    connectionStatus.title = `连接失败 - ${reconnectError.message}`;
                    connectionStatus.className = 'connection-indicator';
                }
            }
        });
        
        // 折叠所有目录按钮点击事件
        collapseBtn.addEventListener('click', collapseAllDirectories);
        
        // 键盘事件处理
        document.addEventListener('keydown', (e) => {
            // 保存文件快捷键
            if ((e.ctrlKey || e.metaKey) && e.key === 's') {
                e.preventDefault();
                saveFile();
            }
            
            // Delete键删除选中的文件或目录
            if ((e.key === 'Delete' || e.key === 'delete') && selectedNode) {
                e.preventDefault();
                const path = selectedNode.dataset.path;
                if (path) {
                    handleContextMenuAction('delete', path);
                }
            }
        });
        
        // 点击其他地方关闭右键菜单
        document.addEventListener('click', () => {
            contextMenu.style.display = 'none';
            if (tabContextMenu) {
                tabContextMenu.style.display = 'none';
            }
        });
        
        // 右键菜单项点击事件
        document.querySelectorAll('.context-menu-item').forEach(item => {
            item.addEventListener('click', (e) => {
                e.stopPropagation();
                const action = item.dataset.action;
                const path = contextMenu.dataset.path;
                handleContextMenuAction(action, path);
            });
        });
        
        // 阻止右键菜单事件冒泡
        contextMenu.addEventListener('contextmenu', (e) => {
            e.preventDefault();
        });
        
        // 添加滚动事件监听器，实时保存滚动位置
        codeEditor.addEventListener('scroll', function() {
            if (activeTabPath) {
                const activeTab = openTabs.find(tab => tab.path === activeTabPath);
                if (activeTab) {
                    activeTab.scrollTop = codeEditor.scrollTop;
                }
            }
        });
        
        // 添加选择事件监听器，实时保存光标位置
        codeEditor.addEventListener('mouseup', function() {
            if (activeTabPath) {
                const activeTab = openTabs.find(tab => tab.path === activeTabPath);
                if (activeTab) {
                    activeTab.selectionStart = codeEditor.selectionStart;
                    activeTab.selectionEnd = codeEditor.selectionEnd;
                }
            }
        });
        
        // 添加键盘事件监听器，实时保存光标位置和检测修改
        codeEditor.addEventListener('keyup', function() {
            if (activeTabPath) {
                const activeTab = openTabs.find(tab => tab.path === activeTabPath);
                if (activeTab) {
                    activeTab.selectionStart = codeEditor.selectionStart;
                    activeTab.selectionEnd = codeEditor.selectionEnd;
                    
                    // 检查内容是否有变化
                    if (activeTab.content !== codeEditor.value) {
                        // 如果内容发生变化，将状态设置为已修改
                        if (!activeTab.isModified) {
                            activeTab.isModified = true;
                            updateTabModifiedStatus(activeTab);
                        }
                    }
                    
                    // 保存内容到临时变量，但不更新tab.content，以确保能继续检测变化
                    // 注意：实际内容保存是在saveFile函数中进行的
                }
            }
        });
        
        // 更新标签的未保存状态显示
        function updateTabModifiedStatus(tab) {
            if (tab && tab.element) {
                const indicator = tab.element.querySelector('.tab-modified-indicator');
                if (indicator) {
                    indicator.style.display = tab.isModified ? 'inline-block' : 'none';
                }
            }
        }
        
        // 在窗口失去焦点时保存所有状态
        window.addEventListener('blur', function() {
            saveActiveTabState();
        });
        // 显示标签右键菜单
        function showTabContextMenu(event, path) {
            // 确保tabContextMenu已初始化
            if (!tabContextMenu) {
                tabContextMenu = document.getElementById('tab-context-menu');
            }
            
            // 确保隐藏其他菜单
            contextMenu.style.display = 'none';
            
            // 先设置路径，再显示菜单
            tabContextMenu.dataset.path = path;
            tabContextMenu.style.left = `${event.clientX}px`;
            tabContextMenu.style.top = `${event.clientY}px`;
            tabContextMenu.style.display = 'block';
        }
        
        // 处理标签右键菜单操作
        function handleTabContextMenuAction(action, path) {
            // 先关闭菜单
            if (tabContextMenu) {
                tabContextMenu.style.display = 'none';
            }
            
            try {
                switch (action) {
                    case 'close':
                        // 关闭当前标签
                        closeTab(path);
                        break;
                        
                    case 'close-others':
                        // 关闭其他标签
                        closeOtherTabs(path);
                        break;
                        
                    case 'close-right':
                        // 关闭右侧标签
                        closeRightTabs(path);
                        break;
                        
                    case 'close-saved':
                        // 关闭已保存的标签
                        closeSavedTabs();
                        break;
                        
                    case 'close-all':
                        // 全部关闭
                        closeAllTabs();
                        break;
                }
            } catch (error) {
                console.error(`执行标签操作 ${action} 失败:`, error);
            }
        }
        
        // 关闭其他标签
        function closeOtherTabs(keepPath) {
            // 保存当前激活的标签路径
            const activePath = activeTabPath;
            
            // 收集需要关闭的标签路径
            const tabsToClose = openTabs.filter(tab => tab.path !== keepPath).map(tab => tab.path);
            
            // 关闭所有其他标签
            tabsToClose.forEach(path => closeTab(path));
            
            // 确保保留的标签是激活的
            if (activePath !== keepPath) {
                activateTab(keepPath);
            }
        }
        
        // 关闭右侧标签
        function closeRightTabs(path) {
            // 找到当前标签的索引
            const currentIndex = openTabs.findIndex(tab => tab.path === path);
            
            if (currentIndex !== -1) {
                // 收集需要关闭的标签路径（当前标签右侧的所有标签）
                const tabsToClose = openTabs.slice(currentIndex + 1).map(tab => tab.path);
                
                // 关闭右侧标签
                tabsToClose.forEach(tabPath => closeTab(tabPath));
            }
        }
        
        // 关闭已保存的标签
        function closeSavedTabs() {
            // 保存当前激活的标签路径
            const activePath = activeTabPath;
            
            // 检查文件是否已保存
            const tabsToClose = [];
            for (const tab of openTabs) {
                // 如果不是当前激活的标签且文件已保存（即没有未保存的修改）
                if (tab.path !== activePath && !tab.isModified) {
                    tabsToClose.push(tab.path);
                }
            }
            
            // 关闭已保存的标签
            tabsToClose.forEach(tabPath => closeTab(tabPath));
        }
        
        // 全部关闭
        function closeAllTabs() {
            // 收集所有标签路径
            const allTabs = [...openTabs].map(tab => tab.path);
            
            // 关闭所有标签
            allTabs.forEach(path => closeTab(path));
        }
        
        // 为现有标签添加右键菜单事件
        function addTabContextMenuEvents() {
            document.querySelectorAll('.tab').forEach(tab => {
                tab.addEventListener('contextmenu', (e) => {
                    if (!e.target.classList.contains('tab-close')) {
                        e.preventDefault();
                        showTabContextMenu(e, tab.dataset.path);
                    }
                });
            });
        }
        
        // 修改addTab函数，为新创建的标签添加右键菜单事件
        const originalAddTab = addTab;
        window.addTab = function(path, content = '') {
            const result = originalAddTab(path, content);
            
            // 为新创建的标签添加右键菜单事件
            setTimeout(() => {
                const tabs = document.querySelectorAll('.tab');
                const newTab = Array.from(tabs).find(tab => tab.dataset.path === path);
                if (newTab) {
                    newTab.addEventListener('contextmenu', (e) => {
                        if (!e.target.classList.contains('tab-close')) {
                            e.preventDefault();
                            showTabContextMenu(e, path);
                        }
                    });
                }
            }, 0);
            
            return result;
        };
        
        // 初始化标签右键菜单
        document.addEventListener('DOMContentLoaded', () => {
            // 初始化标签右键菜单
            tabContextMenu = document.getElementById('tab-context-menu');
            
            // 为标签右键菜单项添加点击事件
            if (tabContextMenu) {
                tabContextMenu.querySelectorAll('.context-menu-item').forEach(item => {
                    item.addEventListener('click', (e) => {
                        e.stopPropagation();
                        const action = item.dataset.action;
                        const path = tabContextMenu.dataset.path;
                        handleTabContextMenuAction(action, path);
                    });
                });
                
                // 阻止右键菜单冒泡
                tabContextMenu.addEventListener('contextmenu', (e) => {
                    e.preventDefault();
                });
            }
            
            // 为现有标签添加右键菜单事件
            addTabContextMenuEvents();
        });
    </script>
</body>
</html>